﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Input;

namespace FrogEngine
{
	public abstract class GameScreen : GameEntityBase, IGameScreen
	{
		public GameScreen(IEngine engine)
			: base(engine)
		{
			transitions = new Dictionary<string, IFSMState>();
		}

		private ScreenManager screenManager;
		public ScreenManager ScreenManager
		{
			get { return screenManager; }
			set { screenManager = value; }
		}

		private TimeSpan transitionOnTime;
		public TimeSpan TransitionOnTime
		{
			get { return transitionOnTime; }
			set { transitionOnTime = value; }
		}

		private TimeSpan transitionOffTime;
		public TimeSpan TransitionOffTime
		{
			get { return transitionOffTime; }
			set { transitionOffTime = value; }
		}

		private double transitionProgress;
		public double TransitionProgress
		{
			get { return transitionProgress; }
			set { transitionProgress = value; }
		}

		public event EventHandler TransitionStarted;

		public event EventHandler TransitionCompleted;

		private string stateName;
		public string StateName
		{
			get { return stateName; }
			set { stateName = value; }
		}

		private Dictionary<string, IFSMState> transitions;
		public IDictionary<string, IFSMState> Transitions
		{
			get { return transitions; }
		}

		public void AddTransition(IFSMState state)
		{
			transitions.Add(state.StateName, state);
		}

		public void RemoveTransition(IFSMState state)
		{
			transitions.Remove(state.StateName);
		}

		public bool IsValidTransition(IFSMState nextState)
		{
			return transitions.ContainsKey(nextState.StateName);
		}

		bool leavingInProgress = false;
		public virtual void OnLeaving()
		{
			leavingInProgress = true;
			TransitionProgress = 0;
			elapsedTime = 0;
			if (TransitionStarted != null)
				TransitionStarted(this, new EventArgs());
		}

		bool enterInProgress = false;
		public virtual void OnEntering()
		{
			enterInProgress = true;
			TransitionProgress = 0;
			elapsedTime = 0;
			if (TransitionStarted != null)
				TransitionStarted(this, new EventArgs());
		}

		private ContentManager contentManager;
		public ContentManager ContentManager
		{
			get { return contentManager; }
			set { contentManager = value; }
		}

		public abstract IEnumerable<string> AssetNames();

		public virtual void LoadContent()
		{
		}

		private double elapsedTime;
		public virtual void Update(GameTime gameTime)
		{
			if (enterInProgress)
			{
				if (TransitionOnTime == TimeSpan.Zero)
					TransitionProgress = 1;
				else
				{
					elapsedTime += gameTime.ElapsedGameTime.TotalSeconds;
					TransitionProgress = elapsedTime / TransitionOnTime.TotalSeconds;
				}
				if (TransitionProgress >= 1)
				{
					TransitionProgress = 1;
					elapsedTime = 0;
					enterInProgress = false;
					if (TransitionCompleted != null)
						TransitionCompleted(this, new EventArgs());
				}
			}

			if (leavingInProgress)
			{
				if (TransitionOffTime == TimeSpan.Zero)
					TransitionProgress = 1;
				else
				{
					elapsedTime += gameTime.ElapsedGameTime.TotalSeconds;
					TransitionProgress = elapsedTime / TransitionOffTime.TotalSeconds;
				}
				if (TransitionProgress >= 1)
				{
					TransitionProgress = 1;
					elapsedTime = 0;
					leavingInProgress = false;
					if (TransitionCompleted != null)
						TransitionCompleted(this, new EventArgs());
				}
			}
		}

		public bool IntersectsFrustum(BoundingFrustum frustum) { return true; }
		public RenderType RenderType { get { return FrogEngine.RenderType.TwoD; } }

		public virtual void Render(GameTime gameTime)
		{
			
		}

		public virtual void HandleInput(GameTime gameTime, PlayerIndex index, GamePadState currentState, GamePadState previousState)
		{

		}

		private PlayerIndex playerIndex;
		public PlayerIndex PlayerIndex
		{
			get { return playerIndex; }
			protected set { playerIndex = value; }
		}

		public virtual void HandleInput(GameTime gameTime, PlayerIndex index, KeyboardState currentState, KeyboardState previousState)
		{

		}
	}
}
